﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

namespace AlarmMusik
{
    public partial class alarmMusikForm : Form
    {
        // Inisialisasi variabel
        private bool isPlayed = false;
        private int alarmIndex = 0;

        public alarmMusikForm()
        {
            InitializeComponent();
        }

        // Nilai default tanggal dianggap 1 Januari 2000 jam 00:00:00
        private DateTime getDefaultDate()
        {
            DateTime dateTime = new DateTime(2000,01,01,0,0,0);
            return dateTime;
        }

        // Baca konfigurasi alarm dari file INI
        private String[] readSavedAlarm(int section)
        {
            String[] alarm = new String[3];
            string sectionPath = "Alarm " + Convert.ToString(section);

            IniHelper iniHelper = new IniHelper();

            alarm[0] = iniHelper.read(sectionPath, "Time");
            alarm[1] = iniHelper.read(sectionPath, "File");
            alarm[2] = iniHelper.read(sectionPath, "Active");

            return alarm;
        }

        // Konversi nilai text jam dari file INI ke array integer
        private int[] splitTime(string timeText)
        {
            String[] splitTimeText = timeText.Split(':');
            int[] timeInt = new int[3];

            timeInt[0] = Convert.ToByte(splitTimeText[0]);
            timeInt[1] = Convert.ToByte(splitTimeText[1]);
            timeInt[2] = Convert.ToByte(splitTimeText[2]);

            return timeInt;
        }

        // Parse nilai waktu alarm dari file INI ke format DateTime
        private DateTime parseSavedTime(String savedAlarm)
        {
            try
            {
                int[] timeText = splitTime(savedAlarm);
                return new DateTime(2000, 01, 01, timeText[0], timeText[1], timeText[2]);
            }
            catch (Exception e)
            {
                return new DateTime(2000, 01, 01, 0, 0, 0);
            }
        }

        // Inisialisasi nilai awal setiap properties
        private void setDefaultValue()
        {
            // Alarm 1
            String[] savedAlarm = readSavedAlarm(1);

            if (savedAlarm[0].Length == 0)
                dateTimePicker1.Value = getDefaultDate();
            else
                dateTimePicker1.Value = parseSavedTime(savedAlarm[0]);

            if (savedAlarm[1].Length == 0)
                alarmFile1.Text = "";
            else
                alarmFile1.Text = savedAlarm[1];

            if (savedAlarm[2].Length == 0)
                alarmAktif1.Checked = false;
            else
                alarmAktif1.Checked = Convert.ToBoolean(savedAlarm[2]);
            
            // Alarm 2
            savedAlarm = readSavedAlarm(2);

            if (savedAlarm[0].Length == 0)
                dateTimePicker2.Value = getDefaultDate();
            else
                dateTimePicker2.Value = parseSavedTime(savedAlarm[0]);

            if (savedAlarm[1].Length == 0)
                alarmFile2.Text = "";
            else
                alarmFile2.Text = savedAlarm[1];

            if (savedAlarm[2].Length == 0)
                alarmAktif2.Checked = false;
            else
                alarmAktif2.Checked = Convert.ToBoolean(savedAlarm[2]);

            // Alarm 3
            savedAlarm = readSavedAlarm(3);

            if (savedAlarm[0].Length == 0)
                dateTimePicker3.Value = getDefaultDate();
            else
                dateTimePicker3.Value = parseSavedTime(savedAlarm[0]);

            if (savedAlarm[1].Length == 0)
                alarmFile3.Text = "";
            else
                alarmFile3.Text = savedAlarm[1];

            if (savedAlarm[2].Length == 0)
                alarmAktif3.Checked = false;
            else
                alarmAktif3.Checked = Convert.ToBoolean(savedAlarm[2]);

            // Alarm 4
            savedAlarm = readSavedAlarm(4);

            if (savedAlarm[0].Length == 0)
                dateTimePicker4.Value = getDefaultDate();
            else
                dateTimePicker4.Value = parseSavedTime(savedAlarm[0]);

            if (savedAlarm[1].Length == 0)
                alarmFile4.Text = "";
            else
                alarmFile4.Text = savedAlarm[1];

            if (savedAlarm[2].Length == 0)
                alarmAktif4.Checked = false;
            else
                alarmAktif4.Checked = Convert.ToBoolean(savedAlarm[2]);

            // Alarm 5
            savedAlarm = readSavedAlarm(5);

            if (savedAlarm[0].Length == 0)
                dateTimePicker5.Value = getDefaultDate();
            else
                dateTimePicker5.Value = parseSavedTime(savedAlarm[0]);

            if (savedAlarm[1].Length == 0)
                alarmFile5.Text = "";
            else
                alarmFile5.Text = savedAlarm[1];

            if (savedAlarm[2].Length == 0)
                alarmAktif5.Checked = false;
            else
                alarmAktif5.Checked = Convert.ToBoolean(savedAlarm[2]);
        }

        // Event untuk timer
        private void mainTimer_Tick(object sender, EventArgs e)
        {
            DateTime dt = new DateTime(2000, 01, 01, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
            timeLabel.Text = String.Format("{0:T}", dt);
            DateTime nt = getNextAlarm();           
            nextAlarmLabel.Text = String.Format("{0:T}", nt);

            if (dt == nt)
            {
                if (!isPlayed)               
                    playAlarm();       
            }

            if (isPlayed)
                testButton.Text = "Berhenti";
            else
                testButton.Text = "Tes";
        }

        // Play alarm music :D
        private void playAlarm()
        {
            PlayMedia playMedia = new PlayMedia();
            isPlayed = false;

            switch (alarmIndex)
            {
                case 1:
                    if (alarmAktif1.Checked && File.Exists(alarmFile1.Text))
                    {
                        playMedia.open(alarmFile1.Text);
                        playMedia.play(false);
                        isPlayed = true;
                    }
                    break;
                case 2:
                    if (alarmAktif2.Checked && File.Exists(alarmFile2.Text))
                    {
                        playMedia.open(alarmFile2.Text);
                        playMedia.play(false);
                        isPlayed = true;
                    }
                    break;
                case 3:
                    if (alarmAktif3.Checked && File.Exists(alarmFile3.Text))
                    {
                        playMedia.open(alarmFile3.Text);
                        playMedia.play(false);
                        isPlayed = true;
                    }
                    break;
                case 4:
                    if (alarmAktif4.Checked && File.Exists(alarmFile4.Text))
                    {
                        playMedia.open(alarmFile4.Text);
                        playMedia.play(false);
                        isPlayed = true;
                    }
                    break;
                case 5:
                    if (alarmAktif5.Checked && File.Exists(alarmFile5.Text))
                    {
                        playMedia.open(alarmFile5.Text);
                        playMedia.play(false);
                        isPlayed = true;
                    }
                    break;
            }
        }

        // Event ketika form utama diload
        private void alarmMusikForm_Load(object sender, EventArgs e)
        {
            mainTimer.Enabled = true;
            setDefaultValue();
        }

        // Event ketika form utama diresize (untuk proses hide)
        private void alarmMusikForm_Resize(object sender, EventArgs e)
        {
            if (FormWindowState.Minimized == WindowState)
            {
                Hide();
            }
        }

        // Event double click mouse untuk hide/show form utama
        private void alarmNotify_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.Visible == false)
            {
                Show();
                WindowState = FormWindowState.Normal;
            }
            else
            {
                Hide();
            }
        }

        // Event penutupan aplikasi
        private void closeButton_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Tutup aplikasi ini?!","Konfirmasi",MessageBoxButtons.YesNo,MessageBoxIcon.Question) == DialogResult.Yes) {
                Application.Exit();
            }
        }

        // Event menyembunyikan form
        private void hideButton_Click(object sender, EventArgs e)
        {           
            Hide();
        }

        // Event menyimpan nilai waktu ke file INI
        private void saveAlarm(DateTimePicker dtp, string alarmSection)
        {
            IniHelper iniHelper = new IniHelper();
            iniHelper.write(alarmSection, "Time", String.Format("{0:T}", dtp.Value));
        }

        // Event menyimpan nilai file alarm ke file INI
        private void saveMusic(string file, string alarmSection)
        {
            IniHelper iniHelper = new IniHelper();
            iniHelper.write(alarmSection, "File", file);
        }

        // Event menyimpan nilai aktivasi alarm ke file INI
        private void saveActive(string active, string alarmSection)
        {
            IniHelper iniHelper = new IniHelper();
            iniHelper.write(alarmSection, "Active", active);
        }

        // Event menyimpan nilai Alarm 1
        private void simpanButton1_Click(object sender, EventArgs e)
        {
            string sectionName = "Alarm 1";
            saveAlarm(dateTimePicker1, sectionName);
            saveMusic(alarmFile1.Text, sectionName);
            saveActive(Convert.ToString(alarmAktif1.Checked), sectionName);
        }

        // Event menyimpan nilai Alarm 2
        private void simpanButton2_Click(object sender, EventArgs e)
        {
            string sectionName = "Alarm 2";
            saveAlarm(dateTimePicker2, sectionName);
            saveMusic(alarmFile2.Text, sectionName);
            saveActive(Convert.ToString(alarmAktif2.Checked), sectionName);
        }

        // Event menyimpan nilai Alarm 3
        private void simpanButton3_Click(object sender, EventArgs e)
        {
            string sectionName = "Alarm 3";
            saveAlarm(dateTimePicker3, sectionName);
            saveMusic(alarmFile3.Text, sectionName);
            saveActive(Convert.ToString(alarmAktif3.Checked), sectionName);

        }

        // Event menyimpan nilai Alarm 4
        private void simpanButton4_Click(object sender, EventArgs e)
        {
            string sectionName = "Alarm 4";
            saveAlarm(dateTimePicker4, sectionName);
            saveMusic(alarmFile4.Text, sectionName);
            saveActive(Convert.ToString(alarmAktif4.Checked), sectionName);
        }

        // Event menyimpan nilai Alarm 5
        private void simpanButton5_Click(object sender, EventArgs e)
        {
            string sectionName = "Alarm 5";
            saveAlarm(dateTimePicker5, sectionName);
            saveMusic(alarmFile5.Text, sectionName);
            saveActive(Convert.ToString(alarmAktif5.Checked), sectionName);
        }

        // Event file browse Alarm 1
        private void browseFile1_Click(object sender, EventArgs e)
        {
            if (openMusic.ShowDialog() == DialogResult.OK)
            {
                alarmFile1.Text = openMusic.FileName;
            }
        }

        // Event file browse Alarm 2
        private void browseFile2_Click(object sender, EventArgs e)
        {
            if (openMusic.ShowDialog() == DialogResult.OK)
            {
                alarmFile2.Text = openMusic.FileName;
            }
        }

        // Event file browse Alarm 3
        private void browseFile3_Click(object sender, EventArgs e)
        {
            if (openMusic.ShowDialog() == DialogResult.OK)
            {
                alarmFile3.Text = openMusic.FileName;
            }
        }

        // Event file browse Alarm 4
        private void browseFile4_Click(object sender, EventArgs e)
        {
            if (openMusic.ShowDialog() == DialogResult.OK)
            {
                alarmFile4.Text = openMusic.FileName;
            }
        }

        // Event file browse Alarm 5
        private void browseFile5_Click(object sender, EventArgs e)
        {
            if (openMusic.ShowDialog() == DialogResult.OK)
            {
                alarmFile5.Text = openMusic.FileName;
            }
        }

        // Event test file musik
        private void testButton_Click(object sender, EventArgs e)
        {
            PlayMedia playMedia = new PlayMedia();
            if (isPlayed)
            {
                playMedia.close();
                isPlayed = false;
            }
            else
                switch (alarmControl.SelectedIndex + 1)
                {
                    case 1:
                        if (File.Exists(alarmFile1.Text))
                        {
                            playMedia.open(alarmFile1.Text);
                            playMedia.play(false);
                            isPlayed = true;
                        }
                        break;
                    case 2:
                        if (File.Exists(alarmFile2.Text))
                        {
                            playMedia.open(alarmFile2.Text);
                            playMedia.play(false);
                            isPlayed = true;
                        }
                        break;
                    case 3:
                        if (File.Exists(alarmFile3.Text))
                        {
                            playMedia.open(alarmFile3.Text);
                            playMedia.play(false);
                            isPlayed = true;
                        }
                        break;
                    case 4:
                        if (File.Exists(alarmFile4.Text))
                        {
                            playMedia.open(alarmFile4.Text);
                            playMedia.play(false);
                            isPlayed = true;
                        }
                        break;
                    case 5:
                        if (File.Exists(alarmFile5.Text))
                        {
                            playMedia.open(alarmFile5.Text);
                            playMedia.play(false);
                            isPlayed = true;
                        }
                        break;
                }
        }

        // Logika menemukan alarm berikut
        private DateTime getNextAlarm()
        {
            SortedList<DateTime, int> slValue = new SortedList<DateTime, int>();
            IniHelper iniHelper = new IniHelper();
            
            String[] savedAlarm = null;

            for (int i=1; i <=5; i++) {
                savedAlarm = readSavedAlarm(i);
                if (savedAlarm[0].Length != 0)
                {
                    slValue.Add(parseSavedTime(savedAlarm[0]), i);
                }
            }
            
            alarmIndex = 0;

            DateTime nextTime = getDefaultDate();
            DateTime currentTime = new DateTime(2000, 01, 01, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);

            if (slValue.Count > 0)
            {
                nextTime = slValue.Keys[0];
                alarmIndex = slValue.Values[0];

                if (slValue.Count > 1)
                {
                    for (int i = 0; i < slValue.Count; i++)
                    {
                        if (nextTime < currentTime)
                        {
                            nextTime = slValue.Keys[i];
                            alarmIndex = slValue.Values[i];
                        }
                    }
                }
            }
           
            return nextTime;
        }

        // Test routine untuk SortedList
        public static void PrintKeysAndValues(SortedList<DateTime,int> myList)
        {
            Console.WriteLine("\t-KEY-\t-VALUE-");
            for (int i = 0; i < myList.Count; i++)
            {
                Console.WriteLine("\t{0}:\t{1}", myList.Keys[i], myList.Values[i]);
            }
            Console.WriteLine();
        }
    }
}
